#include<cstdio>
#include<iostream>
#include<cerrno>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string>
//const uint16_t port= 8080;
using namespace std;

void Usage(char* proc)
{
  cout<<"Usage "<<proc<<" port"<<endl;
}

int main(int argc,char* argv[])
{ 

  if(argc!=2)
  {
    Usage(argv[0]);
    return -1;
  }

  uint16_t port=atoi(argv[1]);//字符串转整数
  
 // 1.创建套接字，打开网络文件
  int sock=socket(AF_INET,SOCK_DGRAM,0);
  if(sock<0)
  {
    cerr<<"socket fail: "<<errno<<endl;
    return 1;
  }

   // 2.给该服务器绑定端口和ip(特殊处理)
  struct sockaddr_in local;
  local.sin_family= AF_INET;
  local.sin_port=htons(port);// 此处的端口号，是我们计算机上的变量，是主机序列
  //需要将人识别的点分十进制，字符串风格IP地址，转化成为4字节整数IP
  //也需要考虑大小端
  //inet_addr(const char* cp);能完成上面的两个工作
  //云服务器，不允许用户直接绑定公网IP，
 // local.sin_addr.s_addr=inet_addr("43.2.2.2");// 点分十进制
  local.sin_addr.s_addr= INADDR_ANY;

   if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)
   {
    // cerr<"bind error: " << errno << endl;
       cout<<"bind fail"<<endl;
     return 2;
   }
   
   //提供服务
   bool quit=false;
   #define NUM 1024
   char buffer[NUM];
  while(!quit)
  {
    struct sockaddr_in peer;
    socklen_t len =sizeof(peer);

  ssize_t cnt= recvfrom(sock,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&peer,&len);
   if(cnt>0)
   {
     buffer[cnt]='\0';
     FILE* fp=popen(buffer,"r");
      
    string echo_hello= buffer;
     //读文件
     char line[2048]={0};
    while( fgets(line,sizeof(line),fp)!=NULL)
    {
      echo_hello +=line;
    }
    if(feof(fp))
    {

    }
     pclose(fp);
    cout<<"client# "<<buffer<<endl;
   

    sendto(sock, echo_hello.c_str(), echo_hello.size(), 0, (struct sockaddr*)&peer,len );//返回消息
  }
   else 
   {
     //TODO
   }

  }

  
  
  return 0;
}
